#include <iostream>
#include <pthread.h>
#include <unistd.h>

using namespace std;

int tickets = 1000;

pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

void *start_routine(void *args)
{
    int cnt = 0;
    string name = static_cast<const char *>(args);
    while (true)
    {
        pthread_mutex_lock(&lock);

        pthread_cond_wait(&cond, &lock);    // 每一个想要申请票的线程都需要去条件变量那里等待
        // pthread_cond_wait调用时，会以原子性的方式，将锁释放，将自己挂起
        // 如果被唤醒了，pthread_cond_wait会重新获取你传入的锁

        if (tickets > 0)
        {
            cout << name << " : " << tickets-- << endl;
            pthread_mutex_unlock(&lock);
            cnt++;
        }
        else
        {
            pthread_mutex_unlock(&lock);
            break;
        }

        usleep(10000);      // 0.1s生成订单
    }
    cout << name << " 抢到的票数 : " << cnt << endl;

    return nullptr;
}

int main()
{
    pthread_t t1, t2, t3, t4, t5;
    pthread_create(&t1, nullptr, start_routine, (void *)"thread - 1");
    pthread_create(&t2, nullptr, start_routine, (void *)"thread - 2");
    pthread_create(&t3, nullptr, start_routine, (void *)"thread - 3");
    pthread_create(&t4, nullptr, start_routine, (void *)"thread - 4");
    pthread_create(&t5, nullptr, start_routine, (void *)"thread - 5");

    while (true)
    {
        // pthread_cond_signal(&cond);    // 每隔0.01s唤醒一个在条件变量下面等待的线程去抢票

        pthread_cond_broadcast(&cond);
        sleep(1);
        // usleep(1000); // 1秒 = 1000毫秒 = 100000微秒
    }

    pthread_join(t1, nullptr);
    pthread_join(t2, nullptr);
    pthread_join(t3, nullptr);
    pthread_join(t4, nullptr);
    pthread_join(t5, nullptr);

    return 0;
}